﻿// -----------------------------------------------------------------------------
// 园丁,是个很简单的管理系统
//  gitee:https://gitee.com/hgflydream/Gardener 
//  issues:https://gitee.com/hgflydream/Gardener/issues 
// -----------------------------------------------------------------------------

using Furion.Schedule;
using Gardener.Core.NotificationSystem;
using Gardener.Weighbridge.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Gardener.Weighbridge.Impl.Jobs
{
    /// <summary>
    /// 定时自动发送读取值任务
    /// </summary>
    [JobDetail("job_AutoReadValueJob", Description = "定时自动发送读取值任务", GroupName = "Weighbridge", Concurrent = false)]
    [Period(2000, TriggerId = "trigger_AutoReadValueJob", Description = "定时自动发送读取值任务")]
    public class AutoReadValueJob : IJob
    {
        private readonly IServiceScopeFactory serviceScopeFactory;
        private readonly ISystemNotificationService systemNotificationService;
        private readonly ILogger<AutoReadValueJob> logger;
        /// <summary>
        /// 定时自动发送读取值任务
        /// </summary>
        /// <param name="serviceScopeFactory"></param>
        /// <param name="systemNotificationService"></param>
        /// <param name="logger"></param>
        public AutoReadValueJob(IServiceScopeFactory serviceScopeFactory, ISystemNotificationService systemNotificationService, ILogger<AutoReadValueJob> logger)
        {
            this.serviceScopeFactory = serviceScopeFactory;
            this.systemNotificationService = systemNotificationService;
            this.logger = logger;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="stoppingToken"></param>
        /// <returns></returns>
        public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
        {

            using var factory = serviceScopeFactory.CreateScope();
            IWeighbridgeConfigService service = factory.ServiceProvider.GetRequiredService<IWeighbridgeConfigService>();
            IWeighbridgeControlService service1 = factory.ServiceProvider.GetRequiredService<IWeighbridgeControlService>();
            List<WeighbridgeConfigDto> list = await service.GetAllUsable();
            long success = 0, error = 0, noConnect = 0 ;
            int maxDegreeOfParallelism = 5; // 允许的最大并发数
            var semaphore = new SemaphoreSlim(maxDegreeOfParallelism);
            var tasks = new List<Task>();
            foreach (WeighbridgeConfigDto config in list)
            {
                tasks.Add(Task.Run(async () =>
                {
                    await semaphore.WaitAsync();
                    try
                    {
                        WeighbridgeNotificationData weighbridgeNotificationData = new WeighbridgeNotificationData(config.DeviceId);
                        if (!await systemNotificationService.ExistsDynamicSubscriber(weighbridgeNotificationData))
                        {
                            Interlocked.Increment(ref noConnect);
                            return;
                        }
                        var result = await service1.ReadValue(config.DeviceId, Enumerable.Range(1, config.ChannelNumber).ToArray(), 24);
                        if (result)
                        {
                            Interlocked.Increment(ref success);
                        }
                        else
                        {
                            Interlocked.Increment(ref error);
                        }
                    }
                    catch (Exception ex)
                    {
                        Interlocked.Increment(ref error);
                        logger.LogError(ex, $"Weighbridge readValue error,id:{config.Id}");
                    }
                    finally
                    {
                        semaphore.Release();
                    }
                }));
                
            }
            await Task.WhenAll(tasks);
            context.Result = $"执行完成，未连接{noConnect}条记录，成功{success}条记录，失败{error}条记录。";
        }
    }
}